use clickhouse::{Client, Row};
use serde::{Deserialize, Serialize};
use tmq::{reply, Context, Message, Result};

#[derive(Debug, Row, Serialize, Deserialize)]
struct MyRow<'a> {
    id: u8,
    name: &'a str,
}

async fn query(id: u8, client: &Client) -> String {
    // todo! 根据需要是否查询缓存, 暂省略。。。

    let mut cursor = client
        .query("SELECT id, name FROM actix.user WHERE id = ?")
        .bind(id)
        .fetch::<MyRow<'_>>()
        .unwrap();

    match cursor.next().await.unwrap() {
        None => format!("Not Found, id = {}", id),
        Some(row) => format!("Ok, id = {}, name = {}", row.id, row.name),
    }
}

#[tokio::main]
async fn main() -> Result<()> {
    let client = Client::default()
        .with_url("http://localhost:8123")
        .with_database("actix");

    // 构建REQ socket
    let mut recv_sock = reply(&Context::new()).bind("tcp://*:10000")?;

    loop {
        let (multipart, send_sock) = recv_sock.recv().await?;

        // ["query", "1"]
        let res = multipart
            .iter()
            .map(|item| item.as_str().unwrap())
            .collect::<Vec<&str>>()[0]
            .split(" ")
            .collect::<Vec<&str>>();

        // str --> int
        let id: u8 = res[1].parse().unwrap();

        // 连接本地Clickhouse，查找相关数据
        let resp: Message = query(id, &client).await.as_bytes().into();

        // 向调用者 回传Response
        recv_sock = send_sock.send(resp.into()).await?;
    }
}
